package com.wistech.solr;

import java.io.IOException;
import java.io.StringReader;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.parser.QueryParser.Operator;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.schema.FieldType;
import org.apache.solr.schema.TextField;
import org.apache.solr.search.QParser;
import org.apache.solr.search.QueryParsing;
import org.apache.solr.search.SolrQueryParser;
import org.apache.solr.search.SyntaxError;

public class ChineseQParser extends QParser {

	private SolrQueryParser solrQueryParser;

	private String opParam;

	public ChineseQParser(String qstr, SolrParams localParams,
			SolrParams params, SolrQueryRequest req, String op) {
		super(qstr, localParams, params, req);
		this.opParam = op;
	}

	public Query parse() throws SyntaxError {
		String qstr = getString();

		String defaultField = getParam(CommonParams.DF);
		if (defaultField == null) {
			defaultField = getReq().getSchema().getDefaultSearchFieldName();
		}
		solrQueryParser = new ChineseSolrQueryParser(this, defaultField);
		String opParam = getParam(QueryParsing.OP);
		if (opParam == null) {
			opParam = this.opParam;
		}
		if (opParam == null) {
			opParam = getReq().getSchema().getQueryParserDefaultOperator();
		}
		if (opParam != null) {
			solrQueryParser
					.setDefaultOperator("AND".equals(opParam) ? Operator.OR
							: Operator.OR);

		}
		return solrQueryParser.parse(qstr);
	}

	/**
	 * 把 queryText 转为 and 关系的 queryparser.
	 * 
	 * @author Steven Liu
	 * 
	 * 
	 */
	public class ChineseSolrQueryParser extends SolrQueryParser {
		public ChineseSolrQueryParser(QParser parser, String defaultField,
				Analyzer analyzer) {
			super(parser, defaultField);
		}

		public ChineseSolrQueryParser(QParser parser, String defaultField) {
			super(parser, defaultField);

		}

		protected Query getFieldQuery(String field, String queryText,
				boolean quoted) throws SyntaxError {
			BooleanClause.Occur occur = QueryParser.Operator.OR
					.equals(getDefaultOperator()) ? Occur.SHOULD : Occur.MUST;
			String qField = field == null ? this.getDefaultField() : field;
			if (qField != null) {
				FieldType ft = schema.getField(qField).getType();
				if (ft instanceof TextField) {
					try {
						// 此字段的分词器
						Analyzer analyzer = ft.getQueryAnalyzer();
						if (analyzer == null) {
							analyzer = ft.getAnalyzer();
						}
						if (analyzer != null) {
							BooleanQuery bq = new BooleanQuery();
							TokenStream ts = analyzer.tokenStream(field,
									new StringReader(queryText));
							ts.reset();
							int endOffset = 0;
							while (ts.incrementToken()) {
								CharTermAttribute ta = (CharTermAttribute) ts
										.getAttribute(CharTermAttribute.class);
								OffsetAttribute oa = (OffsetAttribute) ts
										.getAttribute(OffsetAttribute.class);
								if (oa.startOffset() >= endOffset) {
									bq.add(new TermQuery(new Term(qField, ta
											.toString())), occur);
									endOffset = oa.endOffset();
								} else {
									bq.add(new TermQuery(new Term(qField, ta
											.toString())), occur);
								}
							}
							ts.close();
							return bq;
						}
					} catch (IOException e) {
						throw new SyntaxError(e.getMessage());
					}
				}
			}
			return super.getFieldQuery(field, queryText, quoted);
		}
	}
}
